import time
import traceback

from uiautomator2 import Device

from le_engine.base import LittleEmpire
from le_engine.config import CommonConfig
from utils.logger import log
from utils.utils import CommonUtils, FullGXException, account_config


class Attack:

    def __init__(self, le: LittleEmpire, forever=False, event=None):
        self.le = le
        self.client: Device = self.le.get_client()

        self.re_try_kill_times = 0
        self.forever = forever
        self.event = event
        self.account_config = account_config()

    def wait_attack(self):
        # 如果所有牢笼都在进攻，识别行军最大时间，进行等待
        self.client.click(*CommonConfig.center_position)
        time.sleep(1)
        self.client.click(*CommonConfig.cage_check)

        self.client(textContains="你的部队").wait(timeout=CommonConfig.n_t_o)

        time_info = [i.get_text() for i in self.client(textContains="你的部队")]
        max_seconds = max([CommonUtils.extract_seconds(item) for item in time_info])
        log.info(f"所有牢笼都在进攻，需要等待:{max_seconds}秒", extra={"pk": self.le.pk})
        for remaining in range(max_seconds, 0, -1):
            if self.event and self.event.is_set():
                log.info("已停止刷功勋", extra={"pk": self.le.pk})
                return False, None
            minutes = remaining // 60
            seconds = remaining % 60
            print(f"\r还剩 {minutes} 分 {seconds} 秒", end="", flush=True)
            time.sleep(1)
        log.info("等待结束", extra={"pk": self.le.pk})
        self.client.click(*CommonConfig.close_position)
        time.sleep(5)
        return True, None

    def attack(self):
        # 循环牢笼，发起进攻
        success = []

        while True:
            enemy = []
            for k, _ in self.account_config.get("lineup_config").items():
                gx = CommonConfig.gx_names[int(k[-1]) - 1]

                if self.event and self.event.is_set():
                    log.info(f"{self.le.username} 已停止刷功勋", extra={"pk": self.le.pk})
                    return False, "已停止刷功勋"

                if gx in success:
                    if self.client(text=gx).exists:
                        log.info(f"{gx} 已经发起进攻，跳过", extra={"pk": self.le.pk})
                    continue
                if self.client(text=gx).click_exists(timeout=CommonConfig.n_t_o):
                    enemy.append(gx)
                    time.sleep(1)
                    log.info(f"自己进攻 {gx}", extra={"pk": self.le.pk})
                    self.client.click(0.436, 0.508)
                    if self.client(text="主城部队").wait(timeout=CommonConfig.extra_t_o):
                        log.info("点击读取阵容", extra={"pk": self.le.pk})
                        self.client.click(0.832, 0.334)
                        log.info("选择刷功勋的阵容", extra={"pk": self.le.pk})
                        if self.client(text="功勋").click_exists(timeout=CommonConfig.n_t_o):
                            if not self.client(text="功勋").wait(timeout=CommonConfig.n_t_o):
                                self.client.click(*CommonConfig.right_bottom_position)
                                if self.client(text="可怜可怜城主吧").wait(timeout=CommonConfig.n_t_o):
                                    self.client.click(0.625, 0.43)
                                    self.client.click(0.85, 0.918)
                                    self.le.error_exit("可怜可怜城主吧")
                                elif self.client(textContains="你的部队正在行军赶路呢").wait(timeout=CommonConfig.n_t_o):
                                    self.client.click(0.63, 0.427)
                                    self.client.click(0.85, 0.918)
                                else:
                                    if self.client(text="牢笼").wait(timeout=CommonConfig.net_t_o):
                                        log.info(f"成功发起对：{gx} 的进攻", extra={"pk": self.le.pk})
                                success.append(gx)
                        else:
                            self.le.error_exit("未找到刷功勋的阵容，请配置一个阵容名为《功勋》")
            log.info(f"该页存在 {len(enemy)} 个未进攻功勋号 -> {enemy}", extra={"pk": self.le.pk})

            # if len(success) >= len(CommonConfig.gx_names):
            if len(success) >= len(account_config().get("lineup_config")):
                break

            self.client(text="换一批").click()
            log.info(f"下一页", extra={"pk": self.le.pk})
        log.info(f"成功发起 {len(success)} 次进攻 -> {success}", extra={"pk": self.le.pk})
        time.sleep(3)
        self.le.close_current_page()
        if self.forever:
            return self.wait_attack()
        else:
            self.le.success_exit()

    def check_attack(self):
        # 检查功勋是不是刷满了
        # self.le.enter_a_report()
        # self.client.click(*(0.95, 0.274))
        # TODO 暂不支持
        # if True:
        #     raise FullGXException("今日功勋已经刷满")
        pass

    # @log_decorator
    def repeat_attack(self, cage=None) -> (bool, str):

        if self.event and self.event.is_set():
            log.info("已停止刷功勋", extra={"pk": self.le.pk})
            return False, None

        # 循环执行，刷功勋
        if cage is None:
            self.check_attack()
            self.le.inter_game()
            self.le.find_cage()

        if self.re_try_kill_times > 3:
            log.info("多次尝试失败，请检查脚本", extra={"pk": self.le.pk})
            exit()

        if cage is None:
            cage = self.le.cage_position[0]

        log.info(f"选择 {self.le.cage_position.index(cage) + 1} 号牢笼：{cage}", extra={"pk": self.le.pk})
        self.client.click(*cage)
        time.sleep(1)
        self.client.click(*CommonConfig.cage_check)

        if self.client(textContains="你的部队将于").wait(timeout=CommonConfig.n_t_o):
            log.info("该牢笼正在进攻，跳过。选择下一个牢笼", extra={"pk": self.le.pk})
            self.le.close_current_page()
            try:
                next_index = self.le.cage_position.index(cage) + 1
                if next_index >= len(self.account_config.get("lineup_config")):
                    return self.wait_attack()
                next_cage = self.le.cage_position[next_index]
            except IndexError:
                return self.wait_attack()
            else:
                return True, next_cage

        if self.client(text="你想抓谁做奴隶").wait(timeout=CommonConfig.n_t_o):
            return self.attack()
        else:
            log.info(f"牢笼位置定位异常， 退出重试", extra={"pk": self.le.pk})
            self.re_try_kill_times += 1
            return True, None


def attack(le: LittleEmpire, forever=False, event=None):
    a = Attack(le, forever=forever, event=event)
    try:
        loop, next_cage = True, None
        while loop:
            loop, next_cage = a.repeat_attack(cage=next_cage)

    except FullGXException as e:
        return True, str(e)
    except Exception as e:
        traceback.print_exc()
        return False, str(e)
    else:
        return True, ""